package nextdate;

/**
 *Class that calculates the next day's date.
 *
 * @author ChengMing
 */
public class NextDate {


  /**
   * error message.
   */
  private    final  transient String errorMessage;

  /**
   * Year 2050.
   */
  private  static final  Integer YEAR2050 = 2050;
  /**
   * Month 2.
   */
  private  static  final Integer MONTH2 = 2;
  /**
   * Day 29.
   */
  private  static final Integer DAY29 = 29;
  /**
   * Day 30.
   */
  private static final Integer DAY30 = 30;
  /**
   * Day 28.
   */
  private  static  final Integer DAY28 = 28;
  /**
   * Day31.
   */
  private  static  final  Integer DAY31 = 31;
  /**
   *  Line's length.
   */
  private  static  final  Integer LENGTH = 3;
  /**
   * Number 4.
   */
  private  static  final  Integer FOUR = 4;
  /**
   * Number 6.
   */
  private  static  final  Integer SIX = 6;
  /**
   * Number 3.
   */
  private  static  final  Integer THREE = 3;
  /**
   * Number 9.
   */
  private  static  final  Integer NINE = 9;
  /**
   * Number 11.
   */
  private  static  final  Integer ELEVEN = 11;
  /**
   * Number 12.
   */
  private  static  final  Integer TWELVE = 12;
  /**
   * Number 31.
   */
  private  static  final  Integer THIRTYONE = 31;
  /**
   * Number 1900.
   */
  private  static  final  Integer YEAR1900 = 1900;
  /**
   * Number 100.
   */
  private  static  final  Integer HUNDRED = 100;
  /**
   * Number 400.
   */
  private  static  final  Integer HUNDRED4 = 400;


  /**
   * Initialize message.
   */
  public NextDate() {
    this.errorMessage = "日期输入错误";
  }




  /**
   * Judge whether it is December 31.
   *
   * @param month   Input data <code>month</code> to test;
   * @param day  Input data <code>day</code> to test;
   * @param  message judge if the message is not to stop;
   * @return <code>ture</code>date 12/31,message correct<code>false</code>If not
   */
  public  boolean dayConditionBy1231(final Integer month,
                                     final Integer day, final String message) {
    return  month == TWELVE && day == THIRTYONE && message.equals(errorMessage);
  }

  /**
   * Judge whether the year is a leap year.
   *
   * @param year Input data <code>year</code> to test;
   * @param message judge if the message is not to stop;
   * @return  <code>ture</code> If the year is a leap year;
   *        <code>false</code> If the year is not a leap year
   */
  public  boolean runYearCondition(final Integer year, final String message) {
    final boolean judge = year % FOUR == 0 && year % HUNDRED != 0
           || year % HUNDRED4 == 0;
    return  judge && !message.equals(errorMessage);
  }



  /**
    * Judge whether the date meets the requirements.
   *
    * @param year   Input data <code>year</code> to test;
    * @param month Input data <code>month</code> to test;
    * @param day Input data <code>day</code> to test;
    * @return <code>true</code>If date is in the range<code>false</code>If not
    */
  public  boolean  judgeCondition(final Integer year, final Integer month,
                                  final Integer day) {

    return day < 1 || day > THIRTYONE || month < 1 || month > TWELVE
            || year < YEAR1900 || year > YEAR2050;
  }

  /**
   * Judge whether the month is 4, 6, 9 and 11.
   *
   * @param month
   *        Input data <code>month</code> to test;
   * @return  <code>true</code>  If the month is within the range
   *        <code>false</code> If the month is Not within the range
   */
  public  boolean monthConditionBy46911(final Integer month) {
    return month == FOUR || month == SIX || month == NINE || month == ELEVEN;
  }


  /**
   * Calculate the date of leap year according to the number of days.
   *
   * @param year  Input data <code>year</code> to calculate
   * @param month Input data <code>year</code> to calculate
   * @param day  Input data <code>year</code> to calculate
   * @return <code>message</code> Return information according to the conditions
   */
  @SuppressWarnings("unused")
  public String yearYun(final Integer year,
                        final Integer month, final Integer day) {
    String message = null;
    Integer days = day;
    if (month == MONTH2) {
      if (days > DAY29) {
        message = errorMessage;
      }  else {
        if (days == DAY29) {
          //day == 29
          message = year + "年" + THREE + "月" + 1 + "日";
        } else {
          days += 1;
          message = year + "年" + month + "月" + days + "日";
        }
      }

    } else {
      if (monthConditionBy46911(month)) {
        message =  month46911(year, month, day);
      } else if (month != MONTH2) { // 判断1 3 5 7 8 10月的天数输入

        message =  month1357810(year, month, day);

      }
    }
    return  message;
  }

  /**
   *Calculate the date of a non leap year based on the number of days.
   *
   * @param year Input data <code>year</code> to calculate
   * @param month Input data <code>month</code> to calculate
   * @param day Input data <code>day</code> to calculate
   * @return <code>message</code> Return information according to the conditions
   */
  public  String  yearNotYun(final Integer year,
                             final Integer month, final Integer day) {
    Integer days = day;
    String message = null;
    if (month == MONTH2) {
      if (days > DAY28) {
        message = errorMessage;
      }  else {
        if (days == DAY28) {
          message = year + "年" + THREE + "月" + 1 + "日";
        } else {
          days += 1;
          message = year + "年" + month + "月" + days + "日";
        }
      }
    } else {
      if (monthConditionBy46911(month)) {
        message =  month46911(year, month, day);
      } else if (month != MONTH2) { // 判断1 3 5 7 8 10月的天数输入
        message =  month1357810(year, month, day);

      }
    }
    return  message;
  }

  /**
   * Calculation date, if the month is 4,6,9,11.
   *
   * @param year Input data <code>year</code> to calculate
   * @param month Input data <code>month</code> to calculate
   * @param day  Input data <code>day</code> to calculate
   * @return  Return information according to the  conditions
   */
  public String month46911(final Integer year,
                           final Integer month, final Integer day) {
    final Integer years = year;
    String message;
    Integer days = day;
    Integer months = month;
    if (days > DAY30) {
      message = errorMessage;

    }  else {
      //Month4_6_9_11(month,day);
      if (days == DAY30) {
        months += 1;
        days = 1;
      } else {
        days += 1;
      }
      message = years + "年" + months + "月" + days + "日";

    }
    return message;
  }

  /**
   *  Calculation date, if the month is 1,3,5,7,8,10.
   *
   * @param year Input data <code>year</code> to calculate
   * @param month Input data <code>month</code> to calculate
   * @param day  Input data <code>day</code> to calculate
   * @return  Return information according to the  conditions
   */
  public String  month1357810(final Integer year,
                              final Integer month, final Integer day) {
    final Integer years = year;
    Integer days = day;
    Integer months = month;
    if (days == DAY31) {
      months += 1;
      days = 1;
    } else {
      days += 1;
    }
    return years + "年" + months + "月" + days + "日";

  }

  /**
   * Change String to String[].
   *
   * @param line data to change
   * @return  String[]
   */
  public String[] change(final String line) {
    return line.split(",");
  }
  /**
   * Calculates the next day after a given date.
   *
   * @param line
   *        Given date
   * @return
   *        Next day's date
   */

  public String nextDate(final String line) {
    String messages = null;
    //处理字符串
    String lines = line;

    for (final char c : new char[]{'年', '月', '日'}) {
      lines = lines.replace(c, ',');
    }
    final String[] str = change(lines);

    if (str.length < LENGTH) {
      messages = errorMessage;
    }
    final Integer year = Integer.valueOf(str[0]);
    final Integer month = Integer.valueOf(str[1]);
    final Integer day = Integer.valueOf(str[2]);

    if (judgeCondition(year, month, day) || errorMessage.equals(messages)) {
      messages = errorMessage;

    }
    //判断12月份
    if (dayConditionBy1231(month, day, messages)) {
      //month == 12 && day == 31


      if (year == YEAR2050) {
        messages = errorMessage;

      } else {
        messages = (year + 1) + "年1月1日";

      }

    } else {
      messages = errorMessage;
    }

    // 判断输入的年份是平年还是闰年,来判断当输入2月时天数是否有误
    if (runYearCondition(year, messages)) {
      // 该年是闰年,2月有29天
      messages = yearYun(year, month, day);

    } else if (errorMessage.equals(messages)) {
      messages = errorMessage;
    } else {
      messages = yearNotYun(year, month, day);
    }

    return messages;
  }


}
